﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Threading;
using System.Windows.Forms;
using DataSync.DAL;
using DataSync.Model;

namespace DataSync.BLL
{
    public delegate string GetMessage(DateTime reportDate);

    /// <summary>
    /// 日期同步委托
    /// </summary>
    public delegate bool DelDateSyncData(SyncBase obj, SQLHelper sHelper, SQLHelper tHelper, Sync dataSync, SyncLog syncLog, DateTime? startTime, DateTime dbMaxTime);

    /// <summary>
    /// 全量同步委托
    /// </summary>
    public delegate bool DelFullSyncData(SyncBase obj, SQLHelper sHelper, SQLHelper tHelper, Sync dataSync, SyncLog syncLog);

    public class SyncService
    {
        SyncManage syncManage = new SyncManage();

        private ListBox lbMsg;
        private StatusStrip txtMsg;

        public StatusStrip TxtMsg
        {
            get { return txtMsg; }
            set { txtMsg = value; }
        }

        public ListBox LbMsg
        {
            get { return lbMsg; }
            set { lbMsg = value; }
        }

        #region 判断是否在有效时间段
        /// <summary>
        /// 检查是否在同步时间段内
        /// </summary>
        /// <returns></returns>
        protected bool InTimeSpan()
        {

            int startTime = int.Parse(ConfigurationManager.AppSettings["startTime"]);
            int stopTime = int.Parse(ConfigurationManager.AppSettings["stopTime"]);
            DateTime currentTime = DateTime.Now;

            if (stopTime > startTime)
            {
                if (currentTime.Hour >= startTime && currentTime.Hour < stopTime)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                if (!(currentTime.Hour >= stopTime && currentTime.Hour < startTime))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        #endregion

        #region 程序Run
        /// <summary>
        /// 运行同步服务
        /// </summary>
        public void Run()
        {
            bool flag = true;
            while (true)
            {
                System.Configuration.ConfigurationManager.RefreshSection("appSettings");
                if (InTimeSpan() && flag)
                {
                    if (ProcessData())
                    {
                        flag = false;
                    }
                }

                if (!InTimeSpan())
                {
                    flag = true;
                }

                Thread.Sleep(100);
            }
        }
        #endregion

        #region 重试同步数据
        /// <summary>
        /// 重试同步数据
        /// </summary>
        protected bool RepeatSyncData(DelDateSyncData delDateSyncData, DelFullSyncData delFullSyncData, SyncBase obj, SQLHelper sHelper, SQLHelper tHelper, Sync dataSync, SyncLog syncLog, DateTime? startTime, DateTime dbMaxTime)
        {
            string syncMsg = "";
            bool result = false;
            int count = 0;
            while (!result && count <= 3)
            {
                if (delDateSyncData != null)
                {
                    result = delDateSyncData(obj, sHelper, tHelper, dataSync, syncLog, null, dbMaxTime);
                }
                else if (delFullSyncData != null)
                {
                    result = delFullSyncData(obj, sHelper, tHelper, dataSync, syncLog);
                }

                count++;
                if (!result && count != 3)
                {
                    syncMsg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":" + "本次操作失败，正在重试第" + count + "次";
                    syncManage.ShowSyncMsg(syncMsg);
                    syncManage.Log.Info(syncMsg);
                }
            }
            if (!result)
            {
                syncMsg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":" + "表 " + obj.SourceTableName + " 同步失败，请手动同步。";
                syncManage.ShowSyncMsg(syncMsg);
                syncManage.Log.Info(syncMsg);
            }
            return result;
        }
        #endregion

        #region 处理所有同步数据
        /// <summary>
        /// 处理所有同步数据
        /// </summary>
        /// <returns></returns>
        protected bool ProcessData()
        {
            Sync dataSync = new Sync();
            SyncLog syncLog = new SyncLog();
            syncManage.LbMsg = this.lbMsg;
            syncManage.TxtMsg = this.txtMsg;
            string syncMsg = null;
            string sConnString = System.Configuration.ConfigurationManager.ConnectionStrings["sConnString"].ConnectionString;
            string tConnString = System.Configuration.ConfigurationManager.ConnectionStrings["tConnString"].ConnectionString;
            int maxRepeatCount = int.Parse(ConfigurationManager.AppSettings["maxRepeatCount"]);
            int monthSyncDay = int.Parse(ConfigurationManager.AppSettings["MonthSyncDay"]);
            SQLHelper sHelper = new SQLHelper(sConnString);
            SQLHelper tHelper = new SQLHelper(tConnString);

            try
            {
                syncManage.ClearMsg();

                List<SyncBase> dateIncrementSyncTableList = new List<SyncBase>();
                //List<SyncBase> idIncrementSyncTableList = new List<SyncBase>();
                List<SyncBase> fullSyncTableList = new List<SyncBase>();
                ConcreteCreator concreteCreator = new ConcreteCreator();

                DateTime startTime = DateTime.Now;
                DateTime currentDate = Convert.ToDateTime(sHelper.ExecuteScalar("SELECT GETDATE();"));

                #region 相应的对象添加到各自集合里
                //取得日期同步对象
                foreach (int index in Enum.GetValues(typeof(DateIncrementSyncTable)))
                {
                    if (index < 100 || currentDate.Day == monthSyncDay)
                    {
                        SyncBase syncBaseModel = concreteCreator.CreateDateIncrementSyncTable(index);
                        if (syncBaseModel.IsSubTable)
                        {
                            if (syncBaseModel.SourceTableName == "ACCOUNT_MONTH")
                            {
                                syncBaseModel.TargetTableName += currentDate.AddMonths(-1).Month;
                            }
                            else
                            {
                                syncBaseModel.TargetTableName += currentDate.AddDays(-2).Month;
                            }
                        }
                        dateIncrementSyncTableList.Add(syncBaseModel);
                    }
                }

                //取得全部同步对象
                foreach (int index in Enum.GetValues(typeof(FullSyncTables)))
                {
                    //if (false) //(DEL)
                    SyncBase syncBaseModel = concreteCreator.CreateFullSyncTable(index);
                    //IF SYNC BY DAY ， ADD
                    if (syncBaseModel.IsFullSyncByDay)
                    {
                        fullSyncTableList.Add(syncBaseModel);
                    }
                    else
                    {
                        //IF SYNC BY MONTH AND CURRENTDATE EQUAL MONTHSYNCDAY ， ADD
                        if (currentDate.Day == monthSyncDay)
                        {
                            fullSyncTableList.Add(syncBaseModel);
                        }
                    }
                }
                #endregion

                #region 循环所有集合，挨个同步
                bool syncResult = true;
                //日期同步
                foreach (SyncBase obj in dateIncrementSyncTableList)
                {
                    //日期日同步
                    if (obj.SourceTableName != "ACCOUNT_MONTH")
                    {
                        syncResult = RepeatSyncData(syncManage.IncrementDataSyncByDate, null, obj, sHelper, tHelper, dataSync, syncLog, null, currentDate);
                    }

                    //日期月同步（注意monthSyncDay）
                    if (currentDate.Day == monthSyncDay && obj.SourceTableName == "ACCOUNT_MONTH")
                    {
                        syncResult = syncResult == false ? false : RepeatSyncData(syncManage.IncrementDataSyncByMonth, null, obj, sHelper, tHelper, dataSync, syncLog, null, currentDate);
                    }
                }

                //全量同步
                foreach (SyncBase obj in fullSyncTableList)
                {
                    syncResult = syncResult == false ? false : RepeatSyncData(null, syncManage.FullDataSync, obj, sHelper, tHelper, dataSync, syncLog, null, DateTime.Now);
                }
                #endregion

                syncMsg = "====================================================================================================";
                syncManage.ShowSyncMsg(syncMsg);
                syncManage.Log.Info(syncMsg);

                DateTime finishTime = DateTime.Now;
                syncMsg = finishTime.ToString("yyyy-MM-dd HH:mm:ss") + " ：" + " 本日数据同步全部完成，累计耗时 "
                    + finishTime.Subtract(startTime).Hours + " 小时 "
                    + finishTime.Subtract(startTime).Minutes + " 分 "
                    + finishTime.Subtract(startTime).Seconds + " 秒。";

                syncManage.ShowSyncMsg(syncMsg);
                syncManage.Log.Info(syncMsg);

                //IF ALL SYNC SUCCESS,UPDATE FINISH
                if (syncResult)
                {
                    syncManage.UpdateFinishTime();
                }
                else
                    syncManage.ShowStatusMsg("本次同步有异常，请仔细检查日志。");

                syncMsg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " ： " + "等待下一次同步 ……";
                syncManage.ShowSyncMsg(syncMsg);
                syncManage.Log.Info(syncMsg);

                //释放资源
                sHelper.Dispose();
                tHelper.Dispose();
                syncManage.Dispose();
            }

            catch (Exception ex)
            {
                syncManage.ShowSyncMsg(ex.Message);
                syncManage.Log.Info(ex);
                TraceHelper.WriteLine(ex);
            }

            return true; //不论成功与否，均返回true，以退出本次循环
        }
        #endregion
    }
}
